﻿// Program.cs
// Aleksei Vassiljev
// {4DC17B88-5237-4e95-A60D-72988F554D4F}


using System;
using System.Reflection;
using OracleTools.Core;
using OracleTools.Core.CommandLine;
using System.Threading;
using System.Linq;
using System.Collections.Generic;
using System.Text;


namespace OracleTools.OracleHomeSelector
{
    class Program
    {
        private CommandLineParser parser;

        
        static void Main(string[] args)
        {
            Program app = new Program();
            app.Execute(args);
        }

        public void Execute(string[] args)
        {
            parser = new CommandLineParser();

            SwitchArgument argCurrent = new SwitchArgument("current", "c", "Shows current home's information.");
            SwitchArgument argHelp = new SwitchArgument("help", "h", "Shows this help message.");
            SwitchArgument argList = new SwitchArgument("list", "l", "Shows list of installed oracle homes.");
            ValueArgument argInfo = new ValueArgument("info", "i", "", "Shows information for the specified oracle home");
            SwitchArgument argDetails = new SwitchArgument("details", "d", "Returned detailed information. Works with parameters -current, -list and -set.");
            ValueArgument argSet = new ValueArgument("set", "s", "", "Changes the current oracle home to the specified one. Home's name or number can be specified.");

            parser.NamedArguments.Add(argCurrent);
            parser.NamedArguments.Add(argHelp);
            parser.NamedArguments.Add(argList);
            parser.NamedArguments.Add(argDetails);
            parser.NamedArguments.Add(argInfo);
            parser.NamedArguments.Add(argSet);

            bool bArgParseResult = parser.Parse(args);
            if (!bArgParseResult)
            {
                Console.WriteLine(parser.ParseErrors);
                Console.WriteLine();
                ShowHelp();
                return;
            }

            if (args.Length == 0)
                ShowHelp();
            else if(argCurrent.Exists)
                ShowCurrentHome(argDetails.Exists);
            /*else if(argCurrent.Exists &&!argDetails.Exists)
                ShowCurrentHome(argDetails.Exists);
            else if ((args.Length == 1) && argDetails.Exists)
                ShowCurrentHome(true);*/
            else if (argHelp.Exists)
                ShowHelp();
            else if (argList.Exists)
                ShowList();
            else if (argInfo.Exists)
                ShowHomeInfo(argInfo.Value);
            else if (argSet.Exists)
                ChangeCurrentHome(argSet.Value, argDetails.Exists);
        }
        private OraHome GetHomeById(OraMaster master, string psId)
        {
            OraHome oraHome = null;
            try
            {
                int nId;
                if (int.TryParse(psId, out nId))
                    oraHome = master.Homes[nId - 1];
                else
                    foreach (OraHome home in master.Homes)
                        if (home.Name.ToLower() == psId.ToLower())
                        {
                            oraHome = home;
                            break;
                        }
            }
            catch (Exception)
            {
                Console.Error.WriteLine("Error: specified home was not found");
            }
            return oraHome;
        }
        private void ChangeCurrentHome(string psId, bool pbLogInConsole)
        {
            bool bWorking = true;
            new Thread(() => { Console.Write("setting."); while (bWorking) { Console.Write("."); Thread.Sleep(1000); } }).Start();

            OraMaster master = OraMaster.GetInstance();
            master.LoadData();
            if(pbLogInConsole)
                LogWriter.Writer = Console.Out;

            OraHome oraHomeNew = GetHomeById(master, psId);

            if (oraHomeNew != null)
            {
                master.SetAsCurrent(oraHomeNew);
                bWorking = false;
                Console.WriteLine("\r\nNew oracle home: {0} ({1})", oraHomeNew.Name, oraHomeNew.Path);
            }
            else
            {
                bWorking = false;
                Console.Error.WriteLine("\r\nError: specified home was not found");
            }

            
        }
        private void ShowCurrentHome(bool pbDetails)
        {
            OraMaster master = OraMaster.GetInstance();
            master.LoadData();
            if (master.CurrentHome == null)
                Console.WriteLine("Current Home == null");
            ShowHomeInfo(master.CurrentHome, pbDetails);
        }

        private void ShowHomeInfo(string psId)
        {
            OraMaster master = OraMaster.GetInstance();
            master.LoadData();
            OraHome oraHome = GetHomeById(master, psId);
            if(oraHome != null)
                ShowHomeInfo(oraHome, true);
        }

        private void ShowHomeInfo(OraHome home, bool pbDetails)
        {
            if (pbDetails)
            {
                System.Type t = home.GetType();
                PropertyInfo[] arrProp = t.GetProperties();
                foreach(PropertyInfo prop in arrProp)
                    Console.WriteLine("{0} = {1}", prop.Name, prop.GetValue(home, null));
            }
            else
                Console.WriteLine("{0} - {1}", home.Name, home.Path);
        }

        private void ShowList()
        {
            OraMaster master = OraMaster.GetInstance();
            master.LoadData();
            for (int i = 0; i < master.Homes.Count; i++)
            {
                string sLine;
                if(master.Homes[i].IsCurrent)
                    sLine = "*";
                else
                    sLine = " ";
                sLine += (i + 1).ToString() + ") " + master.Homes[i].Name + " - " + master.Homes[i].Path;
                Console.WriteLine(sLine);
            }
        }
        private void ShowHelp()
        {
            string sVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            string sMsg = @"Oracle Home Selector (Console) - v" + sVersion + @" (http://oratools.codeplex.com)

Usage:
orahome [-c|-l|-h|-i:<HomeNumber|HomeName>|-s:<HomeNumber|HomeName>]

Parameters:
" + parser.ConsolidatedHelpMessage;

            Console.WriteLine(sMsg);
        }
    }
}
